<template>
  <div class="">
    <el-upload  
      :class="'upload_wrapper ' + (fileList.length >= limit ? 'hide ' : '') + size"
      :file-list="fileList"
      :headers="uploadHeaders"
      ref="imageUpload"
      :action="uploadImgUrl"
      :multiple="multiple"
      :show-file-list="true"
      list-type="picture-card"
      :on-preview="handlePictureCardPreview" 
      :on-remove="handleDelete"
      :limit="limit" 
      :on-success="handleSuccess"
      :on-exceed="handleExceed"
      :on-error="handleUploadError"
      :before-upload="handleBeforeUpload"
      :before-remove="handleBeforeRemove"
    >
      <el-icon><Plus /></el-icon>
    </el-upload>
     <!-- 上传提示 -->
     <div class="el-upload__tip" slot="tip" v-if="isShowTip">
      请上传
      <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
      的文件
    </div>

    <preview v-model="showPreview" :url="previewUrl"/>
 
  </div>
</template>

<script setup> 
import feedback from '@/utils/feedback'
import Preview from './preview.vue'
import {useUserStore} from "../../stores/user.js";
import pinia from "../../stores/store.js";
const uploadImgUrl = `${import.meta.env.VITE_APP_BASE_API}/file/upload`;
const baseUrl = import.meta.env.VITE_APP_BASE_API;
const fileList = ref([]); 
const number = ref(0)
const uploadList = ref([])
const imageUpload = ref(null)
const previousFileList = ref([])
const previewUrl = ref('')
const showPreview = ref(false)
const uploadHeaders=ref( ``)
const store = useUserStore(pinia)
if(store.token){
  uploadHeaders.value={
    Authorization: `Bearer ${store.token}`
  }
}
const emit = defineEmits(["update:modelValue"])

const props = defineProps({
  size: {
    type: String,
    default: 'default',
  },
  modelValue: {
    type: String,
  },
  multiple: {
    type: Boolean,
    default: false,
  },
  limit: {
    type: Number,
    default: 1,
  },
  fileSize: {
    type: Number,
    default: 5,
  },
  // 文件类型, 例如['png', 'jpg', 'jpeg']
  fileType: {
    type: Array,
    default: () => ["png","jpg", "jpeg"],
  },
  // 是否显示提示
  isShowTip: {
    type: Boolean,
    default: true
  }
}); 

watch( () => props.modelValue, (newVal) => {
    if (newVal) {
      const list = Array.isArray(newVal) ? newVal : newVal.split(',')
        fileList.value = list.map((item) => {
          if (typeof item === 'string') {
            item = { name: item, url: item }
          }
          return item
        })
    } else {
      fileList.value = []
    }
  },
  { immediate: true, deep: true }
)


const showTip = computed(()=>{
  return props.isShowTip && (props.fileType || props.fileSize);
})

const handleSuccess = (res, file) => {  
  if (res.code === 200) { 
    uploadList.value.push({ name: res.data.alt, url: res.data.url }); 
    uploadedSuccessfully();
  } else {
    number.value--;
    feedback.closeLoading();
    feedback.msgSuccess(res.msg);
    imageUpload.value.handleRemove(file);
    uploadedSuccessfully();
  }  
}
 
// 上传失败
const handleUploadError = () =>  {
  feedback.msgError("上传图片失败，请重试");
  feedback.closeLoading();
}

 // 上传结束处理
 const uploadedSuccessfully = () => {
  if (number.value > 0 && uploadList.value.length === number.value) {
    fileList.value = fileList.value.concat(uploadList.value);
    uploadList.value = [];
    number.value = 0;  
    emit("update:modelValue", listToString(fileList.value)); 
    feedback.closeLoading();
  }
}

 // 文件个数超出
const handleExceed = () => {
  feedback.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
}


const listToString = (list, separator) => {
  let strs = "";
  separator = separator || ",";
  for (let i in list) {
    if (list[i].url) {
      strs += list[i].url.replace(baseUrl.value, "") + separator;
    }
  }
  return strs != '' ? strs.slice(0, strs.length - 1) : '';
}

 

const handleBeforeUpload = (file)  => {
  let isImg = false;
  if (props.fileType.length) {
    let fileExtension = "";
    if (file.name.lastIndexOf(".") > -1) {
      fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
    }
    isImg = props.fileType.some(type => {
      if (file.type.indexOf(type) > -1) return true;
      if (fileExtension && fileExtension.indexOf(type) > -1) return true;
      return false;
    });
  } else {
    isImg = file.type.indexOf("image") > -1;
  }

  if (!isImg) {
    feedback.msgError(`文件格式不正确, 请上传${props.fileType.join("/")}图片格式文件!`) 
    return false;
  }
  // if (props.fileSize) {
  //   const isLt = file.size / 1024 / 1024 < props.fileSize;
  //   if (!isLt) { 
  //     feedback.msgError(`上传头像图片大小不能超过 ${props.fileSize} MB!`) 
  //     return false;
  //   }
  // }
  feedback.loading("正在上传图片，请稍候...");
   number.value ++;
 }

 
 const handleBeforeRemove = (uploadFile, uploadFiles) => { 
    previousFileList.value = [...fileList.value];
 }

const handleDelete = (file) => {  
  const findex = previousFileList.value.map(f => f.name).indexOf(file.name); 
  if(findex > -1) {
    fileList.value.splice(findex, 1);  
    emit("update:modelValue", listToString(fileList.value)); 
  } 
};

const handlePictureCardPreview = (uploadFile) => { 
  previewUrl.value = uploadFile.url
  showPreview.value = true
};


</script>

<style scoped lang="scss">
.upload_wrapper.hide :deep() .el-upload--picture-card {
  display: none;
}
.default :deep() .el-upload--picture-card {
  --el-upload-picture-card-size: 140px;
}
.mini :deep() .el-upload--picture-card {
  --el-upload-picture-card-size: 60px;
}
.default :deep() .el-upload-list--picture-card{
  --el-upload-list-picture-card-size: 140px;
}
.mini :deep() .el-upload-list--picture-card{
  --el-upload-list-picture-card-size: 60px; 
}
.avatar-uploader .avatar {
  width: 100px;
  height: 100px;
  display: block;
}

:deep() .el-upload-list--picture-card .el-upload-list__item-thumbnail{
  object-fit: cover;
}
.addImg {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100px;
  height: 100px;
  span {
    font-size: 14px;
  }
  .avatar-uploader-icon {
    font-size: 20px !important;
    color: #8c939d;
  }
}
.avatar-uploader :deep() .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.avatar-uploader :deep() .el-upload:hover {
  border-color: var(--el-color-primary);
}
</style>
